﻿using FastSocket.Server;
using SocketTool.Com.Args;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SocketTool.Com.UDP.Server
{
    public class UDPServer : ISocket
    {
        private UDPServerProtocol mProtocol;
        public UdpService Service;
        private UdpServer<UDPServerMessage> mUdpServer;
        public event EventHandler<ConnectionArgs> SocketConnectionChangedEvent;
        public event EventHandler<ReceiveMessageArgs> ReceiveMessageEvent;

        public UDPServer(int port, int messageBufferSize = 2048)
        {
            this.Service = new UdpService(this);
            this.mProtocol = new UDPServerProtocol();
            this.mUdpServer = new UdpServer<UDPServerMessage>(port, messageBufferSize, mProtocol, Service);
        }

        public void Close()
        {
            this.mUdpServer.Stop();
        }

        public bool Open()
        {
            this.mUdpServer.Start();
            return true;
        }

        public void Send(string msg, int count)
        {
            throw new NotImplementedException();
        }

        public void SetCustomerProtocol(CustomerProtocol protocol)
        {
            this.mProtocol.Protocols = protocol;
        }


        public class UdpService : AbsUdpService<UDPServerMessage>
        {
            public UdpService(UDPServer server)
            {
                this.mServer = server;
            }
            public ConcurrentDictionary<string, UdpSession> Sessions = new ConcurrentDictionary<string, UdpSession>();
            private UDPServer mServer;
            public override void OnError(UdpSession session, Exception ex)
            {
                base.OnError(session, ex);
            }

            public override void OnReceived(UdpSession session, UDPServerMessage message)
            {
                base.OnReceived(session, message);
                if (!this.Sessions.ContainsKey(session.RemoteEndPoint.ToString()))
                    this.Sessions.TryAdd(session.RemoteEndPoint.ToString(), session);

                string msg = Encoding.UTF8.GetString(message.Payload);
                this.mServer.ReceiveMessageEvent?.Invoke(this, new Args.ReceiveMessageArgs(session.RemoteEndPoint, msg));
            }
        }
    }
}
